package com.kusiri.kframework.metadata
{
	import flash.utils.describeType;
	import flash.utils.getDefinitionByName;
	
	/**
	 * 
	 */
	public class KfApplicationConfiguration
	{
		/**
		 * 
		 */
		public var initialUi : KfInitialUiConfiguration;
		
		/**
		 * 
		 */
		public var uiContainer : KfUiContainerConfiguration; 
		
		/**
		 * 
		 */
		protected var _componentInterfaceLookup : Array;
		
		/**
		 * 
		 */
		protected var _componentConfiguration : Array  = [];
		
		/**
		 * 
		 */
		public function KfApplicationConfiguration()
		{			

		}
		
		/**
		 * 
		 */
		public static function fromXml(applicationXmlConfiguration:XML) : KfApplicationConfiguration
		{
			var config : KfApplicationConfiguration = new KfApplicationConfiguration();

			for each ( var component : XML in applicationXmlConfiguration.components.component)
			{
				config.setComponentConfiguration(KfComponentConfiguration.fromXml(config, component));
			} 
			
			config.uiContainer = KfUiContainerConfiguration.fromXml(applicationXmlConfiguration.uicontainer[0]);
			
			config.initialUi = KfInitialUiConfiguration.fromXml(applicationXmlConfiguration.initialUi[0]);

			return config;
		}

		
		public function toXml() : XML
		{
			var xml : XML =  <application></application>;
			
			xml.appendChild( initialUi.toXml() );
			
			xml.appendChild( uiContainer.toXml() );
			
			var components : XML = <components></components>;
			for each ( var componentConfig : KfComponentConfiguration in _componentConfiguration )
			{
				components.appendChild(componentConfig.toXml());
			}
			
			xml.appendChild(components);
			
			return xml;
		}

		/**
		 * 
		 */
		public function setComponentConfiguration(config : KfComponentConfiguration ) : void
		{
			_componentConfiguration[config.id] = config;
			_componentInterfaceLookup = null;
		}
		
		/**
		 * 
		 */
		public function getComponentConfiguration(componentId:String) : KfComponentConfiguration
		{
			return _componentConfiguration[componentId];
		}


		
		public function getComponentsImplementing( interfase : String ) : Array
		{
			return componentInterfaceLookup[processInterfaceName(interfase)];
		}
		
		protected function processInterfaceName( interfase : String ) : String
		{
			return interfase.replace(/\.|:/ig, '_');
		} 
		
		/**
		 *
		 */
		protected function get componentInterfaceLookup() : Array
		{
			if (_componentInterfaceLookup) return _componentInterfaceLookup;
			
			_componentInterfaceLookup = new Array();
		
			for each (var componentConfig : KfComponentConfiguration in _componentConfiguration)
			{
				var info : XML = describeType(getDefinitionByName(componentConfig.clazz) );
				
				for each ( var interfase : XML in info.factory.implementsInterface)
				{
					var interfaceClass : String = processInterfaceName(interfase.@type)
					_componentInterfaceLookup[interfaceClass] ||= [];
					_componentInterfaceLookup[interfaceClass].push(getComponentConfiguration(componentConfig.id));
				}
				
			}

			return _componentInterfaceLookup;
		}
		
		
		/**
		 * Returns a XML object that describes the components 
		 * available for use in this application
		 */
		public function get availableComponents() : XML
		{
			return 	  <node>
			            <node label="UI">
			            	<node label="Image"/>
			            	<node label="HTML"/>
			                <node label="Table"/>
			                <node label="Bar Chart"/>
			                <node label="Salesforce">
			                	<node label="Accordion"/>
			                	<node label="View / Edit"/>
			                </node>
			            </node>
			            <node label="Data">
			                <node label="RSS Feed"/>
			                <node label="Atom Feed"/>
			                <node label="Salesforce">
			                	<node label="SOQL Query Builder"/>
			                	<node label="My Tasks"/>
			                	<node label="Recent deals"/>
			                </node>
			            </node>
			            <node label="Services">
			                <node label="Salesforce"/>
			            </node>
			        </node>    ;
		}
		

	}
}